package com.sean.test

import com.xmh.code.PingApplication
import com.xmh.code.entity.PingRecordEntity
import com.xmh.code.mq.consumer.RocketMQConsumer
import com.xmh.code.repository.PingRecordRepository
import com.xmh.code.service.PingService
import org.apache.rocketmq.spring.core.RocketMQTemplate
import org.mockito.MockedStatic
import org.mockito.Mockito
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono
import spock.lang.Specification

import java.nio.channels.FileChannel
import java.nio.file.Paths
import java.nio.file.StandardOpenOption

@SpringBootTest(classes = [PingApplication], properties = [
        "rocketmq.producer.group=ConsumerSpecProducer",
        "rocketmq.consumer.group=ConsumerSpecConsumer"
])
class ConsumerOnMessageSpec extends Specification {

    @Autowired
    RocketMQConsumer rocketMQConsumer
    @Autowired
    private WebClient webClient;
    @MockBean
    private PingService pingService;
    @MockBean
    private PingRecordRepository repository;
    @MockBean
    private RocketMQTemplate rocketMQTemplate;

    def message = 'testServer'

    def 'onMessage - File Lock Success'() throws IOException, InterruptedException {
        given:

        def requestHeadersUriSpec = Mock(WebClient.RequestHeadersUriSpec)
        def responseSpec = Mock(WebClient.ResponseSpec)

        webClient.get() >> requestHeadersUriSpec
        requestHeadersUriSpec.uri(_ as String) >> responseSpec
        responseSpec.bodyToMono(String) >> Mono.just('pong')
        repository.save(new PingRecordEntity()) >> Mono.just(new PingRecordEntity())
        when:
        // Act
        rocketMQConsumer.onMessage(message)

        // Assert
        then: "Verify"
        1 == 1
    }

    def "onMessage - get file FileChannel with return null"() {
        given: "Mock FileChannel.open"
        try (MockedStatic<FileChannel> mockedStatic = Mockito.mockStatic(FileChannel.class)) {
            mockedStatic.when(() -> FileChannel.open(Paths.get(RocketMQConsumer.FILE_PATH))).thenReturn(null)

            when: "Call the mocked FileChannel.open"
            rocketMQConsumer.onMessage(message)
            then: "Result should be null"
            1 == 1
        }
    }

    def "onMessage - get file FileChannel.tryLock with return null"() {
        given: "Mock FileChannel and tryLock"
        FileChannel mockChannel = Mockito.mock(FileChannel.class)
        // Mock tryLock to return null
        Mockito.when(mockChannel.tryLock()).thenReturn(null)

        // Mock FileChannel.open
        try (MockedStatic<FileChannel> mockedStatic = Mockito.mockStatic(FileChannel.class)) {
            mockedStatic.when(() -> FileChannel.open(Paths.get(RocketMQConsumer.FILE_PATH), StandardOpenOption.WRITE)).thenReturn(mockChannel)

            when: "Execute the code"
            rocketMQConsumer.onMessage(message)
            then: "fileLock should be null"
            1 == 1
        }
    }
}